library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
all10x <- readRDS('output/10x-180504')
cannot open compressed file 'output/10x-180504', probable reason 'No such file or directory'Error in gzfile(file, "rb") : cannot open the connection

One cluster in the data contains cells from all samples

TSNEPlot(all10x, group.by='sample_name', pt.size=0.1)

Cluster 12

TSNEPlot(all10x, group.by='res.0.5', pt.size=0.1, do.label=T)

Marker genes

markers <- read.table('output/markergenes/180504/markers_10x-180504_res.0.5_negbinom', sep='\t', header=T)
cannot open file 'output/markergenes/180504/markers_10x-180504_res.0.5_negbinom': No such file or directoryError in file(file, "rt") : cannot open the connection

Positive markers

as.data.frame(mixture_pos)

Negative markers

as.data.frame(mixture_neg)

Top 10 positive markers

VlnPlot(all10x, features.plot=toupper(mixture_pos$gene[1:10]), group.by='res.0.5', point.size.use=-1, nCol=2, x.lab.rot=T, size.x.use=10)

Top 10 negative markers

VlnPlot(all10x, features.plot=toupper(mixture_neg$gene[1:10]), group.by='res.0.5', point.size.use=-1, nCol=2, x.lab.rot=T, size.x.use=10)

Plots

all10x@meta.data$mixture <- ifelse(all10x@meta.data$res.0.5==12, "mixture", "rest")
VlnPlot(all10x, features.plot=c('nGene', 'MALAT1', 'NEAT1', 'FN1', 'ITGB1', 'COL1A1', 'COL1A2', 'percent.mito'), group.by='mixture', point.size.use=-1, nCol=4)

Gene set enrichment

Nr of cells

Sample composition in cluster 12.

cluster12 <- SubsetData(all10x, cells.use=rownames(all10x@meta.data)[which(all10x@meta.data$res.0.5 %in% 12)])
rotate_x <- function(data, column_to_plot, labels_vec, rot_angle) {
     plt <- barplot(data[[column_to_plot]], col='steelblue', xaxt="n")
     text(plt, par("usr")[3], labels = labels_vec, srt = rot_angle, adj = c(1.1,1.1), xpd = TRUE, cex=1)
}
rotate_x((cluster12@meta.data %>% count(sample_name))[,2], 'n', as.vector(unlist((cluster12@meta.data %>% count(sample_name))[,1])), 45)

scmap results

Add line breaks for legend

Stressed cell analysis

length(stress_genes)
[1] 140
stress_genes
  [1] Actg1    Btg1     Cxcl1    Dnajb4   Errfi1   H3f3b    Hspb1    Irf1     Klf6     Mir22hg 
 [11] Nfkbia   Pcf11    Pxdc1    Sdc4     Srf      Tpm3     Usp2     Gadd45g  Ankrd1   Btg2    
 [21] Cyr61    Dusp1    Fam132b  Hipk3    Hsph1    Irf8     Klf9     Mt1      Nfkbiz   Pde4b   
 [31] Rap1b    Serpine1 Srsf5    Tppp3    Wac      Hspe1    Arid5a   Ccnl1    Dcn      Dusp8   
 [41] Fos      Hsp90aa1 Id3      Itpkc    Litaf    Mt2      Nop58    Per1     Rassf1   Skil    
 [51] Srsf7    Tra2a    Zc3h12a  Ier5     Atf3     Ccrn4l   Ddx3x    Egr1     Fosb     Hsp90ab1
 [61] Idi1     Jun      Lmna     Myadm    Nppc     Phlda1   Rhob     Slc10a6  Stat3    Tra2b   
 [71] Zfand5   Kcne4    Atf4     Cebpb    Ddx5     Egr2     Fosl2    Hspa1a   Ier2     Junb    
 [81] Maff     Myc      Nr4a1    Pnp      Rhoh     Slc38a2  Tagln2   Trib1    Zfp36    Bag3    
 [91] Cebpd    Des      Eif1     Gadd45a  Hspa1b   Ier3     Jund     Mafk     Myd88    Odc1    
[101] Pnrc1    Ripk1    Slc41a1  Tiparp   Tubb4b   Zfp36l1  Bhlhe40  Cebpg    Dnaja1   Eif5    
[111] Gcc1     Hspa5    Ifrd1    Klf2     Mcl1     Nckap5l  Osgin1   Ppp1cc   Sat1     Socs3   
[121] Tnfaip3  Tubb6    Zfp36l2  Brd2     Csrnp1   Dnajb1   Erf      Gem      Hspa8    Il6     
[131] Klf4     Midn     Ncoa7    Oxnad1   Ppp1r15a Sbno2    Sqstm1   Tnfaip6  Ubc      Zyx     
140 Levels: Actg1 Ankrd1 Arid5a Atf3 Atf4 Bag3 Bhlhe40 Brd2 Btg1 Btg2 Ccnl1 Ccrn4l ... Zyx

Cluster 12 is the mixture cluster. Check markers MALAT1 and NEAT1 to be sure:

Are any of the stress genes in the DE genes for the mixture cluster?

3 of the 140 genes were found in the positive markers for the mixture cluster, 54 in the negative numbers. Similar numbers were found for the other clusters in the data. These results indicate that the mixture cluster does not consist of stressed cells.

Figures for report

get_violin_plot <- function(x){
  return(VlnPlot(all10x, features.plot=c(x), point.size.use=-1, group.by='mixture', size.title.use=14, remove.legend=T) + theme(axis.title.x=element_blank()))
}
fig2_first_row <- plot_grid(
  TSNEPlot(all10x, group.by='sample_name', pt.size=0.1),
  TSNEPlot(all10x, group.by='predicted_labels_fat_breaks', pt.size=0.1) + theme(legend.key.height=unit(1, "cm")),
  labels=c('a', 'b'), rel_widths=c(48/100, 52/100)
)

fig2_violin <- plot_grid(
  get_violin_plot('nGene'),
  get_violin_plot('MALAT1'),
  get_violin_plot('NEAT1'),
  get_violin_plot('FN1'),
  get_violin_plot('ITGB1'),
  get_violin_plot('COL1A1'),
  get_violin_plot('COL1A2'),
  get_violin_plot('percent.mito'),
  labels=c('d', 'e', 'f', 'g', 'h', 'i', 'j', 'k'), nrow=2
)
fig2_barplot <- plot_grid(ggplot(data=cluster12@meta.data %>% count(sample_name), aes(x=sample_name, y=n)) +
  geom_bar(stat="identity", position='dodge') + 
  scale_y_continuous(expand=c(0,0)) +
  theme(axis.line.y=element_blank(), axis.ticks.y=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank()) +
  coord_flip(), labels=c('c'))
fig2_second_row <- plot_grid(fig2_barplot, fig2_violin, rel_widths=c(2/8, 6/8))
fig2 <- plot_grid(
  fig2_first_row,
  fig2_second_row,
  nrow=2
)
fig2

#save_plot("plots/180504_mixture.pdf", fig2, base_width=12, base_height=9)
# get_violin_plot <- function(x){
#   return(VlnPlot(all10x, features.plot=c(x), point.size.use=-1, group.by='mixture', size.title.use=14, remove.legend=T) + theme(axis.title.x=element_blank()))
# }
# 
# fig2_first_row <- plot_grid(
#   TSNEPlot(all10x, group.by='sample_name', pt.size=0.1) + theme(legend.position=c(0.1, 0.5), legend.key = element_blank(), legend.background= element_rect(fill=alpha('white', 0.8), size=0.5, linetype='solid', colour=alpha('black', 0.3))),
#   DimPlot(all10x, reduction.use='tsne', cells.highlight = rownames(all10x@meta.data)[all10x@meta.data$res.0.5 == 12], cols.highlight='blue', cols.use='gray', pt.size=0.1),
#   labels=c('a', 'b')
# )
# 
# fig2_violin <- plot_grid(
#   get_violin_plot('nGene'),
#   get_violin_plot('MALAT1'),
#   get_violin_plot('NEAT1'),
#   get_violin_plot('FN1'),
#   get_violin_plot('ITGB1'),
#   get_violin_plot('COL1A1'),
#   get_violin_plot('COL1A2'),
#   get_violin_plot('percent.mito'),
#   labels=c('d', 'e', 'f', 'g', 'h', 'i', 'j', 'k'), nrow=2
# )
# 
# fig2_barplot <- plot_grid(ggplot(data=cluster12@meta.data %>% count(sample_name), aes(x=sample_name, y=n)) +
#   geom_bar(stat="identity", position='dodge') + 
#   scale_y_continuous(expand=c(0,0)) +
#   theme(axis.line.y=element_blank(), axis.ticks.y=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank()) +
#   coord_flip(), labels=c('c'))
# 
# fig2_second_row <- plot_grid(fig2_barplot, fig2_violin, rel_widths=c(2/8, 6/8))
# 
# fig2 <- plot_grid(
#   fig2_first_row,
#   fig2_second_row,
#   nrow=2
# )
# 
# fig2
# 
# #save_plot("plots/180504_mixture.pdf", fig2, base_width=12, base_height=10)
write.table(stressed_cells, 'tables/10x-180504-stressed-cells-analysis.txt', sep='\t')
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGdQcm9maWxlUikKYGBgCgoKYGBge3J9CmFsbDEweCA8LSByZWFkUkRTKCdvdXRwdXQvMTB4LTE4MDUwNCcpCmBgYAoKT25lIGNsdXN0ZXIgaW4gdGhlIGRhdGEgY29udGFpbnMgY2VsbHMgZnJvbSBhbGwgc2FtcGxlcwoKYGBge3J9ClRTTkVQbG90KGFsbDEweCwgZ3JvdXAuYnk9J3NhbXBsZV9uYW1lJywgcHQuc2l6ZT0wLjEpCmBgYAoKQ2x1c3RlciAxMgoKYGBge3J9ClRTTkVQbG90KGFsbDEweCwgZ3JvdXAuYnk9J3Jlcy4wLjUnLCBwdC5zaXplPTAuMSwgZG8ubGFiZWw9VCkKYGBgCgojTWFya2VyIGdlbmVzCgpgYGB7cn0KbWFya2VycyA8LSByZWFkLnRhYmxlKCdvdXRwdXQvbWFya2VyZ2VuZXMvMTgwNTA0L21hcmtlcnNfMTB4LTE4MDUwNF9yZXMuMC41X25lZ2Jpbm9tJywgc2VwPSdcdCcsIGhlYWRlcj1UKQptaXh0dXJlIDwtIG1hcmtlcnNbbWFya2VycyRjbHVzdGVyID09IDEyLF0KbWl4dHVyZSA8LSBtaXh0dXJlW21peHR1cmUkcF92YWxfYWRqIDwgMC4wNSxdCm1peHR1cmVfcG9zIDwtIG1peHR1cmVbb3JkZXIoLW1peHR1cmUkYXZnX2xvZ0ZDKSxdCm1peHR1cmVfbmVnIDwtIG1peHR1cmVbb3JkZXIobWl4dHVyZSRhdmdfbG9nRkMpLF0KYGBgCgpQb3NpdGl2ZSBtYXJrZXJzIAoKYGBge3J9CmFzLmRhdGEuZnJhbWUobWl4dHVyZV9wb3MpCmBgYAoKTmVnYXRpdmUgbWFya2VycwoKYGBge3J9CmFzLmRhdGEuZnJhbWUobWl4dHVyZV9uZWcpCmBgYAoKVG9wIDEwIHBvc2l0aXZlIG1hcmtlcnMgCgpgYGB7ciBmaWcxLCBmaWcuaGVpZ2h0ID0gMTUsIGZpZy53aWR0aCA9IDEwLCBmaWcuYWxpZ24gPSAiY2VudGVyIn0KVmxuUGxvdChhbGwxMHgsIGZlYXR1cmVzLnBsb3Q9dG91cHBlcihtaXh0dXJlX3BvcyRnZW5lWzE6MTBdKSwgZ3JvdXAuYnk9J3Jlcy4wLjUnLCBwb2ludC5zaXplLnVzZT0tMSwgbkNvbD0yLCB4LmxhYi5yb3Q9VCwgc2l6ZS54LnVzZT0xMCkKYGBgCgpUb3AgMTAgbmVnYXRpdmUgbWFya2VycwoKYGBge3IgZmlnMiwgZmlnLmhlaWdodCA9IDE1LCBmaWcud2lkdGggPSAxMCwgZmlnLmFsaWduID0gImNlbnRlciJ9ClZsblBsb3QoYWxsMTB4LCBmZWF0dXJlcy5wbG90PXRvdXBwZXIobWl4dHVyZV9uZWckZ2VuZVsxOjEwXSksIGdyb3VwLmJ5PSdyZXMuMC41JywgcG9pbnQuc2l6ZS51c2U9LTEsIG5Db2w9MiwgeC5sYWIucm90PVQsIHNpemUueC51c2U9MTApCmBgYAoKUGxvdHMKCmBgYHtyIGZpZzQsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5LCBmaWcuYWxpZ24gPSAiY2VudGVyIn0KYWxsMTB4QG1ldGEuZGF0YSRtaXh0dXJlIDwtIGlmZWxzZShhbGwxMHhAbWV0YS5kYXRhJHJlcy4wLjU9PTEyLCAibWl4dHVyZSIsICJyZXN0IikKVmxuUGxvdChhbGwxMHgsIGZlYXR1cmVzLnBsb3Q9YygnbkdlbmUnLCAnTUFMQVQxJywgJ05FQVQxJywgJ0ZOMScsICdJVEdCMScsICdDT0wxQTEnLCAnQ09MMUEyJywgJ3BlcmNlbnQubWl0bycpLCBncm91cC5ieT0nbWl4dHVyZScsIHBvaW50LnNpemUudXNlPS0xLCBuQ29sPTQpCmBgYAoKCiNHZW5lIHNldCBlbnJpY2htZW50CgpgYGB7cn0KZ3NlYV9yZXZpZ28gPC0gcmVhZC50YWJsZSgndGFibGVzL1Jldmlnb19taXh0dXJlLWNsdXN0ZXJfY2xlYW5lZC50eHQnLCBoZWFkZXI9VCwgc2VwPSdcdCcpCmdzZWFfcmV2aWdvCmBgYAoKCiNOciBvZiBjZWxscwoKU2FtcGxlIGNvbXBvc2l0aW9uIGluIGNsdXN0ZXIgMTIuIAoKYGBge3J9CmNsdXN0ZXIxMiA8LSBTdWJzZXREYXRhKGFsbDEweCwgY2VsbHMudXNlPXJvd25hbWVzKGFsbDEweEBtZXRhLmRhdGEpW3doaWNoKGFsbDEweEBtZXRhLmRhdGEkcmVzLjAuNSAlaW4lIDEyKV0pCnJvdGF0ZV94IDwtIGZ1bmN0aW9uKGRhdGEsIGNvbHVtbl90b19wbG90LCBsYWJlbHNfdmVjLCByb3RfYW5nbGUpIHsKICAgICBwbHQgPC0gYmFycGxvdChkYXRhW1tjb2x1bW5fdG9fcGxvdF1dLCBjb2w9J3N0ZWVsYmx1ZScsIHhheHQ9Im4iKQogICAgIHRleHQocGx0LCBwYXIoInVzciIpWzNdLCBsYWJlbHMgPSBsYWJlbHNfdmVjLCBzcnQgPSByb3RfYW5nbGUsIGFkaiA9IGMoMS4xLDEuMSksIHhwZCA9IFRSVUUsIGNleD0xKQp9CnJvdGF0ZV94KChjbHVzdGVyMTJAbWV0YS5kYXRhICU+JSBjb3VudChzYW1wbGVfbmFtZSkpWywyXSwgJ24nLCBhcy52ZWN0b3IodW5saXN0KChjbHVzdGVyMTJAbWV0YS5kYXRhICU+JSBjb3VudChzYW1wbGVfbmFtZSkpWywxXSkpLCA0NSkKYGBgCgojc2NtYXAgcmVzdWx0cwoKYGBge3J9ClRTTkVQbG90KGFsbDEweCwgZ3JvdXAuYnk9J3ByZWRpY3RlZF9sYWJlbHNfZmF0JywgcHQuc2l6ZT0wLjEpCmBgYAoKQWRkIGxpbmUgYnJlYWtzIGZvciBsZWdlbmQKCmBgYHtyfQphbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0X2JyZWFrcyA9IGFzLnZlY3RvcihhbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0KQphbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0X2JyZWFrc1t3aGljaChhbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0ID09ICdtZXNlbmNoeW1hbCBzdGVtIGNlbGwgb2YgYWRpcG9zZScpXSA9ICdtZXNlbmNoeW1hbFxuc3RlbSBjZWxsXG5vZiBhZGlwb3NlJwphbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0X2JyZWFrc1t3aGljaChhbGwxMHhAbWV0YS5kYXRhJHByZWRpY3RlZF9sYWJlbHNfZmF0ID09ICdzbW9vdGggbXVzY2xlIGNlbGwnKV0gPSAnc21vb3RoXG5tdXNjbGUgY2VsbCcKYGBgCgpgYGB7cn0KVFNORVBsb3QoYWxsMTB4LCBncm91cC5ieT0ncHJlZGljdGVkX2xhYmVsc19mYXRfYnJlYWtzJywgcHQuc2l6ZT0wLjEpICsgdGhlbWUobGVnZW5kLmtleS5oZWlnaHQ9dW5pdCgxLCAiY20iKSkKYGBgCgoKI1N0cmVzc2VkIGNlbGwgYW5hbHlzaXMKCmBgYHtyfQpzdHJlc3NfZ2VuZXMgPC0gcmVhZC50YWJsZSgnL3JhaWQ1L3Byb2plY3RzL3RpbXNoZWwvc2MtYXJjX2xpcmEvc3JjL2RhdGEtZ2VuZWxpc3RzLzE3MTIxOS12YW5fZGVuX0JyaW5rMjAxNy1nZW5lc19hZmZlY3RlZF9ieV9kaXNzb2NpYXRpb24uY3N2JywgaGVhZGVyPVQpICU+JSBwdWxsKDEpCmxlbmd0aChzdHJlc3NfZ2VuZXMpCmBgYAoKYGBge3J9CnN0cmVzc19nZW5lcwpgYGAKCgpgYGB7cn0KZGVfZ2VuZXMgPC0gcmVhZC50YWJsZSgnb3V0cHV0L21hcmtlcmdlbmVzLzE4MDUwNC9tYXJrZXJzXzEweC0xODA1MDRfcmVzLjAuNV9uZWdiaW5vbScsIGhlYWRlcj1UKQpkZV9nZW5lcyA8LSBkZV9nZW5lc1tkZV9nZW5lcyRwX3ZhbF9hZGogPCAwLjA1LF0KYGBgCgpDbHVzdGVyIDEyIGlzIHRoZSBtaXh0dXJlIGNsdXN0ZXIuIENoZWNrIG1hcmtlcnMgTUFMQVQxIGFuZCBORUFUMSB0byBiZSBzdXJlOgoKYGBge3IgZmlnNywgZmlnLmhlaWdodCA9IDMsIGZpZy53aWR0aCA9IDEwLCBmaWcuYWxpZ24gPSAiY2VudGVyIn0KVmxuUGxvdChhbGwxMHgsIGdyb3VwLmJ5PSdyZXMuMC41JywgZmVhdHVyZXMucGxvdD1jKCdNQUxBVDEnLCAnTkVBVDEnKSwgcG9pbnQuc2l6ZS51c2UgPS0xKQpgYGAKCkFyZSBhbnkgb2YgdGhlIHN0cmVzcyBnZW5lcyBpbiB0aGUgREUgZ2VuZXMgZm9yIHRoZSBtaXh0dXJlIGNsdXN0ZXI/CgpgYGB7cn0KZGVfZ2VuZXNfcG9zIDwtIGRlX2dlbmVzW2RlX2dlbmVzJGF2Z19sb2dGQyA+IDAsIF0KZGVfZ2VuZXNfbmVnIDwtIGRlX2dlbmVzW2RlX2dlbmVzJGF2Z19sb2dGQyA8IDAsIF0KCmludGVyc2VjdF9wb3MgPC0gbGlzdCgpCmludGVyc2VjdF9uZWcgPC0gbGlzdCgpCm5fcG9zIDwtIGxpc3QoKQpuX25lZyA8LSBsaXN0KCkKcGVyY19wb3MgPC0gbGlzdCgpCnBlcmNfbmVnIDwtIGxpc3QoKQoKZm9yIChpIGluIHVuaXF1ZShkZV9nZW5lcyRjbHVzdGVyKSl7CiAgYyA8LSBwYXN0ZSgnY2x1c3RlcicsIGkpCgogIGdlbmVzX3BvcyA8LSBkZV9nZW5lc19wb3NbZGVfZ2VuZXNfcG9zJGNsdXN0ZXIgPT0gaSwgJ2dlbmUnXQogIGdlbmVzX25lZyA8LSBkZV9nZW5lc19uZWdbZGVfZ2VuZXNfbmVnJGNsdXN0ZXIgPT0gaSwgJ2dlbmUnXQogIAogIGludGVyc2VjdF9wb3NbW2NdXSA8LSBsZW5ndGgoaW50ZXJzZWN0KHRvdXBwZXIoc3RyZXNzX2dlbmVzKSwgZ2VuZXNfcG9zKSkKICBpbnRlcnNlY3RfbmVnW1tjXV0gPC0gbGVuZ3RoKGludGVyc2VjdCh0b3VwcGVyKHN0cmVzc19nZW5lcyksIGdlbmVzX25lZykpCiAgbl9wb3NbW2NdXSA8LSBsZW5ndGgoZ2VuZXNfcG9zKQogIG5fbmVnW1tjXV0gPC0gbGVuZ3RoKGdlbmVzX25lZykKICBwZXJjX3Bvc1tbY11dIDwtIChpbnRlcnNlY3RfcG9zW1tjXV0gLyBuX3Bvc1tbY11dKSAqIDEwMAogIHBlcmNfbmVnW1tjXV0gPC0gKGludGVyc2VjdF9uZWdbW2NdXSAvIG5fbmVnW1tjXV0pICogMTAwCn0KCnN0cmVzc2VkX2NlbGxzIDwtIGRhdGEuZnJhbWUoCiAgc2hhcmVkLnBvcy5nZW5lcz11bmxpc3QoaW50ZXJzZWN0X3BvcyksCiAgc2hhcmVkLm5lZy5nZW5lcz11bmxpc3QoaW50ZXJzZWN0X25lZyksCiAgbl9wb3M9dW5saXN0KG5fcG9zKSwKICBuX25lZz11bmxpc3Qobl9uZWcpLAogIHBlcmNfcG9zPXVubGlzdChwZXJjX3BvcyksCiAgcGVyY19uZWc9dW5saXN0KHBlcmNfbmVnKQogICkKCnN0cmVzc2VkX2NlbGxzIDwtIHN0cmVzc2VkX2NlbGxzW29yZGVyKHJvd25hbWVzKHN0cmVzc2VkX2NlbGxzKSksXQpzdHJlc3NlZF9jZWxscwpgYGAKCjMgb2YgdGhlIDE0MCBnZW5lcyB3ZXJlIGZvdW5kIGluIHRoZSBwb3NpdGl2ZSBtYXJrZXJzIGZvciB0aGUgbWl4dHVyZSBjbHVzdGVyLCA1NCBpbiB0aGUgbmVnYXRpdmUgbnVtYmVycy4gU2ltaWxhciBudW1iZXJzIHdlcmUgZm91bmQgZm9yIHRoZSBvdGhlciBjbHVzdGVycyBpbiB0aGUgZGF0YS4gVGhlc2UgcmVzdWx0cyBpbmRpY2F0ZSB0aGF0IHRoZSBtaXh0dXJlIGNsdXN0ZXIgZG9lcyBub3QgY29uc2lzdCBvZiBzdHJlc3NlZCBjZWxscy4gCgojRmlndXJlcyBmb3IgcmVwb3J0CgpgYGB7ciBmaWc1LCBmaWcuaGVpZ2h0ID0gOSwgZmlnLndpZHRoID0gMTIsIGZpZy5hbGlnbiA9ICJjZW50ZXIifQpnZXRfdmlvbGluX3Bsb3QgPC0gZnVuY3Rpb24oeCl7CiAgcmV0dXJuKFZsblBsb3QoYWxsMTB4LCBmZWF0dXJlcy5wbG90PWMoeCksIHBvaW50LnNpemUudXNlPS0xLCBncm91cC5ieT0nbWl4dHVyZScsIHNpemUudGl0bGUudXNlPTE0LCByZW1vdmUubGVnZW5kPVQpICsgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSkpCn0KCmZpZzJfZmlyc3Rfcm93IDwtIHBsb3RfZ3JpZCgKICBUU05FUGxvdChhbGwxMHgsIGdyb3VwLmJ5PSdzYW1wbGVfbmFtZScsIHB0LnNpemU9MC4xKSwKICBUU05FUGxvdChhbGwxMHgsIGdyb3VwLmJ5PSdwcmVkaWN0ZWRfbGFiZWxzX2ZhdF9icmVha3MnLCBwdC5zaXplPTAuMSkgKyB0aGVtZShsZWdlbmQua2V5LmhlaWdodD11bml0KDEsICJjbSIpKSwKICBsYWJlbHM9YygnYScsICdiJyksIHJlbF93aWR0aHM9Yyg0OC8xMDAsIDUyLzEwMCkKKQoKZmlnMl92aW9saW4gPC0gcGxvdF9ncmlkKAogIGdldF92aW9saW5fcGxvdCgnbkdlbmUnKSwKICBnZXRfdmlvbGluX3Bsb3QoJ01BTEFUMScpLAogIGdldF92aW9saW5fcGxvdCgnTkVBVDEnKSwKICBnZXRfdmlvbGluX3Bsb3QoJ0ZOMScpLAogIGdldF92aW9saW5fcGxvdCgnSVRHQjEnKSwKICBnZXRfdmlvbGluX3Bsb3QoJ0NPTDFBMScpLAogIGdldF92aW9saW5fcGxvdCgnQ09MMUEyJyksCiAgZ2V0X3Zpb2xpbl9wbG90KCdwZXJjZW50Lm1pdG8nKSwKICBsYWJlbHM9YygnZCcsICdlJywgJ2YnLCAnZycsICdoJywgJ2knLCAnaicsICdrJyksIG5yb3c9MgopCgpmaWcyX2JhcnBsb3QgPC0gcGxvdF9ncmlkKGdncGxvdChkYXRhPWNsdXN0ZXIxMkBtZXRhLmRhdGEgJT4lIGNvdW50KHNhbXBsZV9uYW1lKSwgYWVzKHg9c2FtcGxlX25hbWUsIHk9bikpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHBvc2l0aW9uPSdkb2RnZScpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpICsKICB0aGVtZShheGlzLmxpbmUueT1lbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpICsKICBjb29yZF9mbGlwKCksIGxhYmVscz1jKCdjJykpCgpmaWcyX3NlY29uZF9yb3cgPC0gcGxvdF9ncmlkKGZpZzJfYmFycGxvdCwgZmlnMl92aW9saW4sIHJlbF93aWR0aHM9YygyLzgsIDYvOCkpCgpmaWcyIDwtIHBsb3RfZ3JpZCgKICBmaWcyX2ZpcnN0X3JvdywKICBmaWcyX3NlY29uZF9yb3csCiAgbnJvdz0yCikKCmZpZzIKCnNhdmVfcGxvdCgicGxvdHMvMTgwNTA0X21peHR1cmUucGRmIiwgZmlnMiwgYmFzZV93aWR0aD0xMiwgYmFzZV9oZWlnaHQ9OSkKCmBgYAoKCmBgYHtyIGZpZzYsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTIsIGZpZy5hbGlnbiA9ICJjZW50ZXIifQojIGdldF92aW9saW5fcGxvdCA8LSBmdW5jdGlvbih4KXsKIyAgIHJldHVybihWbG5QbG90KGFsbDEweCwgZmVhdHVyZXMucGxvdD1jKHgpLCBwb2ludC5zaXplLnVzZT0tMSwgZ3JvdXAuYnk9J21peHR1cmUnLCBzaXplLnRpdGxlLnVzZT0xNCwgcmVtb3ZlLmxlZ2VuZD1UKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpKQojIH0KIyAKIyBmaWcyX2ZpcnN0X3JvdyA8LSBwbG90X2dyaWQoCiMgICBUU05FUGxvdChhbGwxMHgsIGdyb3VwLmJ5PSdzYW1wbGVfbmFtZScsIHB0LnNpemU9MC4xKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj1jKDAuMSwgMC41KSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJhY2tncm91bmQ9IGVsZW1lbnRfcmVjdChmaWxsPWFscGhhKCd3aGl0ZScsIDAuOCksIHNpemU9MC41LCBsaW5ldHlwZT0nc29saWQnLCBjb2xvdXI9YWxwaGEoJ2JsYWNrJywgMC4zKSkpLAojICAgRGltUGxvdChhbGwxMHgsIHJlZHVjdGlvbi51c2U9J3RzbmUnLCBjZWxscy5oaWdobGlnaHQgPSByb3duYW1lcyhhbGwxMHhAbWV0YS5kYXRhKVthbGwxMHhAbWV0YS5kYXRhJHJlcy4wLjUgPT0gMTJdLCBjb2xzLmhpZ2hsaWdodD0nYmx1ZScsIGNvbHMudXNlPSdncmF5JywgcHQuc2l6ZT0wLjEpLAojICAgbGFiZWxzPWMoJ2EnLCAnYicpCiMgKQojIAojIGZpZzJfdmlvbGluIDwtIHBsb3RfZ3JpZCgKIyAgIGdldF92aW9saW5fcGxvdCgnbkdlbmUnKSwKIyAgIGdldF92aW9saW5fcGxvdCgnTUFMQVQxJyksCiMgICBnZXRfdmlvbGluX3Bsb3QoJ05FQVQxJyksCiMgICBnZXRfdmlvbGluX3Bsb3QoJ0ZOMScpLAojICAgZ2V0X3Zpb2xpbl9wbG90KCdJVEdCMScpLAojICAgZ2V0X3Zpb2xpbl9wbG90KCdDT0wxQTEnKSwKIyAgIGdldF92aW9saW5fcGxvdCgnQ09MMUEyJyksCiMgICBnZXRfdmlvbGluX3Bsb3QoJ3BlcmNlbnQubWl0bycpLAojICAgbGFiZWxzPWMoJ2QnLCAnZScsICdmJywgJ2cnLCAnaCcsICdpJywgJ2onLCAnaycpLCBucm93PTIKIyApCiMgCiMgZmlnMl9iYXJwbG90IDwtIHBsb3RfZ3JpZChnZ3Bsb3QoZGF0YT1jbHVzdGVyMTJAbWV0YS5kYXRhICU+JSBjb3VudChzYW1wbGVfbmFtZSksIGFlcyh4PXNhbXBsZV9uYW1lLCB5PW4pKSArCiMgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHBvc2l0aW9uPSdkb2RnZScpICsgCiMgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkgKwojICAgdGhlbWUoYXhpcy5saW5lLnk9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKSArCiMgICBjb29yZF9mbGlwKCksIGxhYmVscz1jKCdjJykpCiMgCiMgZmlnMl9zZWNvbmRfcm93IDwtIHBsb3RfZ3JpZChmaWcyX2JhcnBsb3QsIGZpZzJfdmlvbGluLCByZWxfd2lkdGhzPWMoMi84LCA2LzgpKQojIAojIGZpZzIgPC0gcGxvdF9ncmlkKAojICAgZmlnMl9maXJzdF9yb3csCiMgICBmaWcyX3NlY29uZF9yb3csCiMgICBucm93PTIKIyApCiMgCiMgZmlnMgojIAojICNzYXZlX3Bsb3QoInBsb3RzLzE4MDUwNF9taXh0dXJlLnBkZiIsIGZpZzIsIGJhc2Vfd2lkdGg9MTIsIGJhc2VfaGVpZ2h0PTEwKQoKYGBgCgoKYGBge3J9CndyaXRlLnRhYmxlKHN0cmVzc2VkX2NlbGxzLCAndGFibGVzLzEweC0xODA1MDQtc3RyZXNzZWQtY2VsbHMtYW5hbHlzaXMudHh0Jywgc2VwPSdcdCcpCmBgYAoK